// RAP [rh] HeapStatus not supported
///*******************************************************************************
// * Copyright (c) 2005, 2007 IBM Corporation and others.
// * All rights reserved. This program and the accompanying materials
// * are made available under the terms of the Eclipse Public License v1.0
// * which accompanies this distribution, and is available at
// * http://www.eclipse.org/legal/epl-v10.html
// *
// * Contributors:
// * IBM Corporation - initial API and implementation
// * Brock Janicyak - brockj@tpg.com.au
// * - Fix for Bug 11142 [HeapStatus] Heap status is updated too frequently
// * - Fix for Bug 192996 [Workbench] Reduce amount of garbage created by HeapStatus
// *******************************************************************************/
//
//package org.eclipse.ui.internal;
//
//import java.lang.reflect.Method;
//
//import org.eclipse.jface.action.Action;
//import org.eclipse.jface.action.IAction;
//import org.eclipse.jface.action.IMenuListener;
//import org.eclipse.jface.action.IMenuManager;
//import org.eclipse.jface.action.MenuManager;
//import org.eclipse.jface.preference.IPreferenceStore;
//import org.eclipse.jface.resource.ImageDescriptor;
//import org.eclipse.jface.util.IPropertyChangeListener;
//import org.eclipse.jface.util.PropertyChangeEvent;
//import org.eclipse.osgi.util.NLS;
//import org.eclipse.swt.SWT;
//import org.eclipse.swt.custom.BusyIndicator;
//import org.eclipse.swt.graphics.Color;
//import org.eclipse.swt.graphics.GC;
//import org.eclipse.swt.graphics.Image;
//import org.eclipse.swt.graphics.Point;
//import org.eclipse.swt.graphics.Rectangle;
//import org.eclipse.swt.widgets.Canvas;
//import org.eclipse.swt.widgets.Composite;
//import org.eclipse.swt.widgets.Display;
//import org.eclipse.swt.widgets.Event;
//import org.eclipse.swt.widgets.Listener;
//import org.eclipse.swt.widgets.Menu;
//
///**
// * The Heap Status control, which shows the heap usage statistics in the window trim.
// *
// * @since 3.1
// */
//public class HeapStatus extends Composite {
//
// private boolean armed;
// private Image gcImage;
// private Color bgCol, usedMemCol, lowMemCol, freeMemCol, topLeftCol, bottomRightCol, sepCol, textCol, markCol, armCol;
// private Canvas button;
// private IPreferenceStore prefStore;
// private int updateInterval;
// private boolean showMax;
// private long totalMem;
// private long prevTotalMem = -1L;
// private long prevUsedMem = -1L;
// private boolean hasChanged;
// private long usedMem;
// private long mark = -1;
// // start with 12x12
// private Rectangle imgBounds = new Rectangle(0,0,12,12);
// private long maxMem = Long.MAX_VALUE;
// private boolean maxMemKnown;
// private float lowMemThreshold = 0.05f;
// private boolean showLowMemThreshold = true;
// private boolean updateTooltip = false;
//
// private final Runnable timer = new Runnable() {
// public void run() {
// if (!isDisposed()) {
// updateStats();
// if (hasChanged) {
// if (updateTooltip) {
// updateToolTip();
// }
// redraw();
// hasChanged = false;
// }
// getDisplay().timerExec(updateInterval, this);
// }
// }
// };
//
// private final IPropertyChangeListener prefListener = new IPropertyChangeListener() {
// public void propertyChange(PropertyChangeEvent event) {
// if (IHeapStatusConstants.PREF_UPDATE_INTERVAL.equals(event.getProperty())) {
// setUpdateIntervalInMS(prefStore.getInt(IHeapStatusConstants.PREF_UPDATE_INTERVAL));
// }
// else if (IHeapStatusConstants.PREF_SHOW_MAX.equals(event.getProperty())) {
// showMax = prefStore.getBoolean(IHeapStatusConstants.PREF_SHOW_MAX);
// }
// }
// };
//
// /**
// * Creates a new heap status control with the given parent, and using
// * the given preference store to obtain settings such as the refresh
// * interval.
// *
// * @param parent the parent composite
// * @param prefStore the preference store
// */
// public HeapStatus(Composite parent, IPreferenceStore prefStore) {
// super(parent, SWT.NONE);
//
// maxMem = getMaxMem();
// maxMemKnown = maxMem != Long.MAX_VALUE;
//
// this.prefStore = prefStore;
// prefStore.addPropertyChangeListener(prefListener);
//
// setUpdateIntervalInMS(prefStore.getInt(IHeapStatusConstants.PREF_UPDATE_INTERVAL));
// showMax = prefStore.getBoolean(IHeapStatusConstants.PREF_SHOW_MAX);
//
// button = new Canvas(this, SWT.NONE);
// button.setToolTipText(WorkbenchMessages.HeapStatus_buttonToolTip);
//
// ImageDescriptor imageDesc = WorkbenchImages.getWorkbenchImageDescriptor("elcl16/trash.gif"); //$NON-NLS-1$
// gcImage = imageDesc.createImage();
// if (gcImage != null) {
// imgBounds = gcImage.getBounds();
// }
// Display display = getDisplay();
// usedMemCol = display.getSystemColor(SWT.COLOR_INFO_BACKGROUND);
// lowMemCol = new Color(display, 255, 70, 70); // medium red
// freeMemCol = new Color(display, 255, 190, 125); // light orange
// bgCol = display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
// sepCol = topLeftCol = armCol = display.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
// bottomRightCol = display.getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW);
// markCol = textCol = display.getSystemColor(SWT.COLOR_INFO_FOREGROUND);
//
// createContextMenu();
//
// Listener listener = new Listener() {
//
// public void handleEvent(Event event) {
// switch (event.type) {
// case SWT.Dispose:
// doDispose();
// break;
// case SWT.Resize:
// Rectangle rect = getClientArea();
// button.setBounds(rect.width - imgBounds.width - 1, 1, imgBounds.width, rect.height - 2);
// break;
// case SWT.Paint:
// if (event.widget == HeapStatus.this) {
// paintComposite(event.gc);
// }
// else if (event.widget == button) {
// paintButton(event.gc);
// }
// break;
// case SWT.MouseUp:
// if (event.button == 1) {
// gc();
// arm(false);
// }
// break;
// case SWT.MouseDown:
// if (event.button == 1) {
// if (event.widget == HeapStatus.this) {
// setMark();
// } else if (event.widget == button) {
// arm(true);
// }
// }
// break;
// case SWT.MouseEnter:
// HeapStatus.this.updateTooltip = true;
// updateToolTip();
// break;
// case SWT.MouseExit:
// if (event.widget == HeapStatus.this) {
// HeapStatus.this.updateTooltip = false;
// } else if (event.widget == button) {
// arm(false);
// }
// break;
// }
// }
//
// };
// addListener(SWT.Dispose, listener);
// addListener(SWT.MouseDown, listener);
// addListener(SWT.Paint, listener);
// addListener(SWT.Resize, listener);
// addListener(SWT.MouseEnter, listener);
// addListener(SWT.MouseExit, listener);
// button.addListener(SWT.MouseDown, listener);
// button.addListener(SWT.MouseExit, listener);
// button.addListener(SWT.MouseUp, listener);
// button.addListener(SWT.Paint, listener);
//
// // make sure stats are updated before first paint
// updateStats();
//
// getDisplay().asyncExec(new Runnable() {
// public void run() {
// if (!isDisposed()) {
// getDisplay().timerExec(updateInterval, timer);
// }
// }
// });
// }
//
// /**
// * Returns the maximum memory limit, or Long.MAX_VALUE if the max is not known.
// */
// private long getMaxMem() {
// long max = Long.MAX_VALUE;
// try {
// // Must use reflect to allow compilation against JCL/Foundation
// Method maxMemMethod = Runtime.class.getMethod("maxMemory", new Class[0]); //$NON-NLS-1$
// Object o = maxMemMethod.invoke(Runtime.getRuntime(), new Object[0]);
// if (o instanceof Long) {
// max = ((Long) o).longValue();
// }
// }
// catch (Exception e) {
// // ignore if method missing or if there are other failures trying to determine the max
// }
// return max;
// }
//
// private void setUpdateIntervalInMS(int interval) {
// updateInterval = Math.max(100, interval);
// }
//
// private void doDispose() {
// prefStore.removePropertyChangeListener(prefListener);
// if (gcImage != null) {
// gcImage.dispose();
// }
//
// if (lowMemCol != null) {
// lowMemCol.dispose();
// }
// if (freeMemCol != null) {
// freeMemCol.dispose();
// }
// }
//
// /* (non-Javadoc)
// * @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean)
// */
// public Point computeSize(int wHint, int hHint, boolean changed) {
// GC gc = new GC(this);
// Point p = gc.textExtent(WorkbenchMessages.HeapStatus_widthStr);
// int height = imgBounds.height;
// // choose the largest of
// // - Text height + margins
// // - Image height + margins
// // - Default Trim heightin
// height = Math.max(height, p.y) + 4;
// height = Math.max(TrimUtil.TRIM_DEFAULT_HEIGHT, height);
// gc.dispose();
// return new Point(p.x + 15, height);
// }
//
// private void arm(boolean armed) {
// if (this.armed == armed) {
// return;
// }
// this.armed = armed;
// button.redraw();
// button.update();
// }
//
// /**
// * Creates the context menu
// */
// private void createContextMenu() {
// MenuManager menuMgr = new MenuManager();
// menuMgr.setRemoveAllWhenShown(true);
// menuMgr.addMenuListener(new IMenuListener() {
// public void menuAboutToShow(IMenuManager menuMgr) {
// fillMenu(menuMgr);
// }
// });
// Menu menu = menuMgr.createContextMenu(this);
// setMenu(menu);
// }
//
// private void fillMenu(IMenuManager menuMgr) {
// menuMgr.add(new SetMarkAction());
// menuMgr.add(new ClearMarkAction());
// menuMgr.add(new ShowMaxAction());
// menuMgr.add(new CloseHeapStatusAction());
//// if (isKyrsoftViewAvailable()) {
//// menuMgr.add(new ShowKyrsoftViewAction());
//// }
// }
//
// /**
// * Sets the mark to the current usedMem level.
// */
// private void setMark() {
// updateStats(); // get up-to-date stats before taking the mark
// mark = usedMem;
// hasChanged = true;
// redraw();
// }
//
// /**
// * Clears the mark.
// */
// private void clearMark() {
// mark = -1;
// hasChanged = true;
// redraw();
// }
//
// private void gc() {
// BusyIndicator.showWhile(getDisplay(), new Runnable() {
// public void run() {
// Thread t = new Thread() {
// public void run() {
// busyGC();
// }};
// t.start();
// while(t.isAlive()) {
// try {
// Display d = getDisplay();
// while(d != null && !d.isDisposed() && d.readAndDispatch()) {
// // loop
// }
// t.join(10);
// } catch (InterruptedException e) {
// Thread.currentThread().interrupt();
// }
// }
// }
// });
// }
//
// private void busyGC() {
// for (int i = 0; i < 2; ++i) {
// System.gc();
// System.runFinalization();
// }
// }
//
// private void paintButton(GC gc) {
// Rectangle rect = button.getClientArea();
//
// if (armed) {
// gc.setBackground(armCol);
// gc.fillRectangle(rect.x, rect.y, rect.width, rect.height);
// }
// if (gcImage != null) {
// int by = (rect.height - imgBounds.height) / 2 + rect.y; // button y
// gc.drawImage(gcImage, rect.x, by);
// }
// }
//
// private void paintComposite(GC gc) {
// if (showMax && maxMemKnown) {
// paintCompositeMaxKnown(gc);
// } else {
// paintCompositeMaxUnknown(gc);
// }
// }
//
// private void paintCompositeMaxUnknown(GC gc) {
// Rectangle rect = getClientArea();
// int x = rect.x;
// int y = rect.y;
// int w = rect.width;
// int h = rect.height;
// int bw = imgBounds.width; // button width
// int dx = x + w - bw - 2; // divider x
// int sw = w - bw - 3; // status width
// int uw = (int) (sw * usedMem / totalMem); // used mem width
// int ux = x + 1 + uw; // used mem right edge
//
// gc.setBackground(bgCol);
// gc.fillRectangle(rect);
// gc.setForeground(sepCol);
// gc.drawLine(dx, y, dx, y + h);
// gc.drawLine(ux, y, ux, y + h);
// gc.setForeground(topLeftCol);
// gc.drawLine(x, y, x+w, y);
// gc.drawLine(x, y, x, y+h);
// gc.setForeground(bottomRightCol);
// gc.drawLine(x+w-1, y, x+w-1, y+h);
// gc.drawLine(x, y+h-1, x+w, y+h-1);
//
// gc.setBackground(usedMemCol);
// gc.fillRectangle(x + 1, y + 1, uw, h - 2);
//
// String s = NLS.bind(WorkbenchMessages.HeapStatus_status, convertToMegString(usedMem), convertToMegString(totalMem));
// Point p = gc.textExtent(s);
// int sx = (rect.width - 15 - p.x) / 2 + rect.x + 1;
// int sy = (rect.height - 2 - p.y) / 2 + rect.y + 1;
// gc.setForeground(textCol);
// gc.drawString(s, sx, sy, true);
//
// // draw an I-shaped bar in the foreground colour for the mark (if present)
// if (mark != -1) {
// int ssx = (int) (sw * mark / totalMem) + x + 1;
// paintMark(gc, ssx, y, h);
// }
// }
//
// private void paintCompositeMaxKnown(GC gc) {
// Rectangle rect = getClientArea();
// int x = rect.x;
// int y = rect.y;
// int w = rect.width;
// int h = rect.height;
// int bw = imgBounds.width; // button width
// int dx = x + w - bw - 2; // divider x
// int sw = w - bw - 3; // status width
// int uw = (int) (sw * usedMem / maxMem); // used mem width
// int ux = x + 1 + uw; // used mem right edge
// int tw = (int) (sw * totalMem / maxMem); // current total mem width
// int tx = x + 1 + tw; // current total mem right edge
//
// gc.setBackground(bgCol);
// gc.fillRectangle(rect);
// gc.setForeground(sepCol);
// gc.drawLine(dx, y, dx, y + h);
// gc.drawLine(ux, y, ux, y + h);
// gc.drawLine(tx, y, tx, y + h);
// gc.setForeground(topLeftCol);
// gc.drawLine(x, y, x+w, y);
// gc.drawLine(x, y, x, y+h);
// gc.setForeground(bottomRightCol);
// gc.drawLine(x+w-1, y, x+w-1, y+h);
// gc.drawLine(x, y+h-1, x+w, y+h-1);
//
// if (lowMemThreshold != 0 && ((double)(maxMem - usedMem) / (double)maxMem < lowMemThreshold)) {
// gc.setBackground(lowMemCol);
// } else {
// gc.setBackground(usedMemCol);
// }
// gc.fillRectangle(x + 1, y + 1, uw, h - 2);
//
// gc.setBackground(freeMemCol);
// gc.fillRectangle(ux + 1, y + 1, tx - (ux + 1), h - 2);
//
// // paint line for low memory threshold
// if (showLowMemThreshold && lowMemThreshold != 0) {
// gc.setForeground(lowMemCol);
// int thresholdX = x + 1 + (int) (sw * (1.0 - lowMemThreshold));
// gc.drawLine(thresholdX, y + 1, thresholdX, y + h - 2);
// }
//
// String s = NLS.bind(WorkbenchMessages.HeapStatus_status,
// convertToMegString(usedMem), convertToMegString(totalMem));
// Point p = gc.textExtent(s);
// int sx = (rect.width - 15 - p.x) / 2 + rect.x + 1;
// int sy = (rect.height - 2 - p.y) / 2 + rect.y + 1;
// gc.setForeground(textCol);
// gc.drawString(s, sx, sy, true);
//
// // draw an I-shaped bar in the foreground colour for the mark (if present)
// if (mark != -1) {
// int ssx = (int) (sw * mark / maxMem) + x + 1;
// paintMark(gc, ssx, y, h);
// }
// }
//
// private void paintMark(GC gc, int x, int y, int h) {
// gc.setForeground(markCol);
// gc.drawLine(x, y+1, x, y+h-2);
// gc.drawLine(x-1, y+1, x+1, y+1);
// gc.drawLine(x-1, y+h-2, x+1, y+h-2);
// }
//
// private void updateStats() {
// Runtime runtime = Runtime.getRuntime();
// totalMem = runtime.totalMemory();
// long freeMem = runtime.freeMemory();
// usedMem = totalMem - freeMem;
//
// if (convertToMeg(prevUsedMem) != convertToMeg(usedMem)) {
// prevUsedMem = usedMem;
// this.hasChanged = true;
// }
//
// if (prevTotalMem != totalMem) {
// prevTotalMem = totalMem;
// this.hasChanged = true;
// }
// }
//
// private void updateToolTip() {
// String usedStr = convertToMegString(usedMem);
// String totalStr = convertToMegString(totalMem);
// String maxStr = maxMemKnown ? convertToMegString(maxMem) : WorkbenchMessages.HeapStatus_maxUnknown;
// String markStr = mark == -1 ? WorkbenchMessages.HeapStatus_noMark : convertToMegString(mark);
// String toolTip = NLS.bind(WorkbenchMessages.HeapStatus_memoryToolTip, new Object[] { usedStr, totalStr, maxStr, markStr });
// if (!toolTip.equals(getToolTipText())) {
// setToolTipText(toolTip);
// }
// }
//
// /**
// * Converts the given number of bytes to a printable number of megabytes (rounded up).
// */
// private String convertToMegString(long numBytes) {
// return NLS.bind(WorkbenchMessages.HeapStatus_meg, new Long(convertToMeg(numBytes)));
// }
//
// /**
// * Converts the given number of bytes to the corresponding number of megabytes (rounded up).
// */
// private long convertToMeg(long numBytes) {
// return (numBytes + (512 * 1024)) / (1024 * 1024);
// }
//
//
// class SetMarkAction extends Action {
// SetMarkAction() {
// super(WorkbenchMessages.SetMarkAction_text);
// }
//
// public void run() {
// setMark();
// }
// }
//
// class ClearMarkAction extends Action {
// ClearMarkAction() {
// super(WorkbenchMessages.ClearMarkAction_text);
// }
//
// public void run() {
// clearMark();
// }
// }
//
// class ShowMaxAction extends Action {
// ShowMaxAction() {
// super(WorkbenchMessages.ShowMaxAction_text, IAction.AS_CHECK_BOX);
// setEnabled(maxMemKnown);
// setChecked(showMax);
// }
//
// public void run() {
// prefStore.setValue(IHeapStatusConstants.PREF_SHOW_MAX, isChecked());
// redraw();
// }
// }
//
// class CloseHeapStatusAction extends Action{
//
// CloseHeapStatusAction(){
// super(WorkbenchMessages.WorkbenchWindow_close );
// }
//
// /* (non-Javadoc)
// * @see org.eclipse.jface.action.IAction#run()
// */
// public void run(){
// dispose();
// }
// }
//
//// /**
//// * Returns whether the Kyrsoft memory monitor view is available.
//// *
//// * @return <code>true</code> if available, <code>false</code> otherwise
//// */
//// private boolean isKyrsoftViewAvailable() {
//// return (Platform.getBundle(IHeapStatusConstants.KYRSOFT_PLUGIN_ID) != null) && PlatformUI.getWorkbench().getViewRegistry().find(IHeapStatusConstants.KYRSOFT_VIEW_ID) != null;
//// }
////
//// class ShowKyrsoftViewAction extends Action {
//// ShowKyrsoftViewAction() {
//// super(WorkbenchMessages.ShowKyrsoftViewAction_text);
//// }
//// public void run() {
//// if (!isKyrsoftViewAvailable()) {
//// MessageDialog.openError(getShell(), WorkbenchMessages.HeapStatus_Error, WorkbenchMessages.ShowKyrsoftViewAction_KyrsoftNotInstalled);
//// return;
//// }
//// IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
//// IWorkbenchPage page = window == null ? null : window.getActivePage();
//// if (page == null) {
//// MessageDialog.openError(getShell(), WorkbenchMessages.HeapStatus_Error, WorkbenchMessages.ShowKyrsoftViewAction_OpenPerspectiveFirst);
//// return;
//// }
//// try {
//// page.showView(IHeapStatusConstants.KYRSOFT_VIEW_ID);
//// }
//// catch (PartInitException e) {
//// String msg = WorkbenchMessages.ShowKyrsoftViewAction_ErrorShowingKyrsoftView;
//// IStatus status = new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, msg, e);
//// ErrorDialog.openError(getShell(), WorkbenchMessages.HeapStatus_Error, msg, status);
//// }
////
//// }
//// }
//
//}
//